
// FovDrivenRadiosityDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FovDrivenRadiosity.h"
#include "FovDrivenRadiosityDlg.h"
#include "afxdialogex.h"
#include "OpenGLDisplay.h"
#include <Radiosity\Parameters.h>
#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CFovDrivenRadiosityDlg dialog




CFovDrivenRadiosityDlg::CFovDrivenRadiosityDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CFovDrivenRadiosityDlg::IDD, pParent)
	, _ambient(FALSE)
	, _fullscreen(FALSE)
	, _meshFilename("")
	, _radiosityAlgorithm(ProgressiveRefinement)
	, _parameters(theApp.GlobalParameters())
	, _visualization(FALSE)
	, _dualView(FALSE)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFovDrivenRadiosityDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_SLIDER_WINDOW, _windowResolutionSlider);
	DDX_Control(pDX, IDC_SLIDER_FPS, _fpsSlider);
	DDX_Control(pDX, IDC_SLIDER_ITEM_BUFFER, _itemBufferSlider);
	DDX_Control(pDX, IDC_SLIDER_SUBDIVISION, _subdivisionSlider);
	DDX_Control(pDX, IDC_SLIDER_SHOOT_LEVEL, _shootLevelSlider);
	DDX_Control(pDX, IDC_SLIDER_FOV_ANGLE, _fovAngleSlider);
	DDX_Control(pDX, IDC_SLIDER_FOV_DECAY_INTERVAL, _fovDecayIntervalSlider);
	DDX_Control(pDX, IDC_SLIDER_UNSHOT_MIPMAP_SHOOT_LEVEL, _unshotMipmapShootLevelSlider);

	DDX_Radio(pDX, IDC_RADIO_PROGRESSIVE, _radiosityAlgorithm);
	DDX_Text(pDX, IDC_EDIT_MESH_FILENAME, _meshFilename);
	DDX_Check(pDX, IDC_CHECK_FULLSCREEN, _fullscreen);
	DDX_Check(pDX, IDC_CHECK_AMBIENT, _ambient);
	DDX_Check(pDX, IDC_CHECK_VISUALIZATION, _visualization);
	DDX_Check(pDX, IDC_CHECK_DUALVIEW, _dualView);
}

BEGIN_MESSAGE_MAP(CFovDrivenRadiosityDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_CLOSE()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_EN_CHANGE(IDC_EDIT_MESH_FILENAME, &CFovDrivenRadiosityDlg::OnEnChangeEditMeshFilename)
	ON_BN_CLICKED(IDC_RUN, &CFovDrivenRadiosityDlg::OnBnClickedRun)
	ON_BN_CLICKED(IDC_BUTTON_MESH_FILENAME, &CFovDrivenRadiosityDlg::OnBnClickedButtonMeshFilename)
	ON_BN_CLICKED(IDC_RADIO_PROGRESSIVE, &CFovDrivenRadiosityDlg::OnBnClickedRadio)
	ON_BN_CLICKED(IDC_RADIO_IMPORTANCE, &CFovDrivenRadiosityDlg::OnBnClickedRadio)
	ON_BN_CLICKED(IDC_RADIO_FOV, &CFovDrivenRadiosityDlg::OnBnClickedRadio)
	ON_BN_CLICKED(IDC_CHECK_FULLSCREEN, &CFovDrivenRadiosityDlg::OnBnClickedCheckFullscreen)
	ON_BN_CLICKED(IDC_CHECK_AMBIENT, &CFovDrivenRadiosityDlg::OnBnClickedCheckAmbient)
	ON_BN_CLICKED(IDC_CHECK_VISUALIZATION, &CFovDrivenRadiosityDlg::OnBnClickedCheckVisualization)
	ON_BN_CLICKED(IDC_CHECK_DUALVIEW, &CFovDrivenRadiosityDlg::OnBnClickedCheckDualView)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_FPS, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderFPS)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_ITEM_BUFFER, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderItemBuffer)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_SUBDIVISION, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderSubdivision)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_WINDOW, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderWindow)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_SHOOT_LEVEL, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderShootLevel)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_FOV_ANGLE, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderFovAngle)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_FOV_DECAY_INTERVAL, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderFovDecayInterval)
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_SLIDER_UNSHOT_MIPMAP_SHOOT_LEVEL, &CFovDrivenRadiosityDlg::OnNMCustomdrawSliderUnshotMipmapShootLevel)
END_MESSAGE_MAP()


// CFovDrivenRadiosityDlg message handlers

BOOL CFovDrivenRadiosityDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	_windowSizes.push_back(WindowSize(500, 500));
	_windowSizes.push_back(WindowSize(360, 360));
	_windowSizes.push_back(WindowSize(480, 270));
	_windowSizes.push_back(WindowSize(1280, 720));
	_windowSizes.push_back(WindowSize(1920, 1080));

	_windowResolutionSlider.SetRange(0, static_cast<int>(_windowSizes.size()) - 1);
	_itemBufferSlider.SetRange(7, 12);
	_subdivisionSlider.SetRange(0, 5);
	_fpsSlider.SetRange(1, 30);
	_shootLevelSlider.SetRange(0, 5);
	_fovAngleSlider.SetRange(10, 45);
	_fovDecayIntervalSlider.SetRange(1, 10);
	_unshotMipmapShootLevelSlider.SetRange(0, 4);

	_meshFilename = CString(_parameters->GetMeshFilename().c_str());
	_radiosityAlgorithm = _parameters->GetRadiosityAlgorithm();
	_fullscreen = _parameters->GetDisplayFullscreen();
	_ambient = _parameters->GetDisplayAmbient();
	_visualization = _parameters->GetDisplayVisualization();
	_dualView = _parameters->GetDualView();

	_subdivisionSlider.SetPos(_parameters->GetSubdivisionLevel());

	int pos = (int)(logf((float)_parameters->GetItemBufferResolution())/logf(2.0));
	_itemBufferSlider.SetPos(pos);

	int width = _parameters->GetWindowWidth();
	int height = _parameters->GetWindowHeight();
	for(unsigned int i = 0; i < _windowSizes.size(); i++)
		if(width == _windowSizes[i].width && height == _windowSizes[i].height)
			_windowResolutionSlider.SetPos(i);

	_fpsSlider.SetPos(_parameters->GetRequestedFPS());
	_shootLevelSlider.SetPos(_parameters->GetShootLevel());
	_fovAngleSlider.SetPos(_parameters->GetFovAngle());
	_fovDecayIntervalSlider.SetPos(_parameters->GetFovDecayInterval());
	_unshotMipmapShootLevelSlider.SetPos(_parameters->GetUnshotMipmapShootLevel());

	GetDlgItem(IDC_STATIC_WINDOW)->EnableWindow(!_fullscreen);
	GetDlgItem(IDC_SLIDER_WINDOW)->EnableWindow(!_fullscreen);
	GetDlgItem(IDC_STATIC_WINDOW_RESOLUTION_STATIC)->EnableWindow(!_fullscreen);

	UpdateData(false);

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CFovDrivenRadiosityDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CFovDrivenRadiosityDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CFovDrivenRadiosityDlg::OnBnClickedRun()
{
	UpdateData(true);
	theApp.WriteParameters();
	this->ShowWindow(SW_HIDE);
	OpenGLMainLoop(theApp.GlobalParameters());
	this->ShowWindow(SW_SHOW);
	this->BringWindowToTop();
}

void CFovDrivenRadiosityDlg::OnClose()
{
	OnOK();
}

void CFovDrivenRadiosityDlg::OnOK()
{
	UpdateData(true);
	theApp.WriteParameters();
	CDialogEx::OnOK();
}

void CFovDrivenRadiosityDlg::OnBnClickedButtonMeshFilename()
{
	UpdateData( true );

	CString filter, extension("obj");
	CStringA pathName;
	filter.LoadString(IDS_OBJ_FILTER);
	CFileDialog fileDialog(TRUE, extension, NULL, OFN_READONLY | OFN_FILEMUSTEXIST, (LPCTSTR)filter, this);
	if(fileDialog.DoModal() != IDOK)
		return;

	pathName = fileDialog.GetPathName();
	_meshFilename = CString(pathName);
	CStringA temp(_meshFilename);
	_parameters->SetMeshFilename(std::string(temp));

	UpdateData(false);
}

void CFovDrivenRadiosityDlg::OnBnClickedRadio()
{
	UpdateData(true);

	_parameters->SetRadiosityAlgorithm((RadiosityAlgorithm)_radiosityAlgorithm);
}

void CFovDrivenRadiosityDlg::OnBnClickedCheckFullscreen()
{
	UpdateData(true);

	_parameters->SetDisplayFullscreen(_fullscreen != 0);
	GetDlgItem(IDC_STATIC_WINDOW)->EnableWindow(!_fullscreen);
	GetDlgItem(IDC_SLIDER_WINDOW)->EnableWindow(!_fullscreen);
	GetDlgItem(IDC_STATIC_WINDOW_RESOLUTION_STATIC)->EnableWindow(!_fullscreen);
}

void CFovDrivenRadiosityDlg::OnBnClickedCheckAmbient()
{
	UpdateData(true);

	_parameters->SetDisplayAmbient(_ambient != 0);
}

void CFovDrivenRadiosityDlg::OnBnClickedCheckVisualization()
{
	UpdateData(true);

	_parameters->SetDisplayVisualization(_visualization != 0);
}

void CFovDrivenRadiosityDlg::OnBnClickedCheckDualView()
{
	UpdateData(true);

	_parameters->SetDualView(_dualView != 0);
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderWindow(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	int width = _windowSizes[_windowResolutionSlider.GetPos()].width;
	int height = _windowSizes[_windowResolutionSlider.GetPos()].height;
	_parameters->SetWindowWidth(width);
	_parameters->SetWindowHeight(height);
	CStringA text;
	text.Format("%i x %i", width, height);
	SetDlgItemTextW(IDC_STATIC_WINDOW, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderItemBuffer(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	int rez = (int)pow(2.0, _itemBufferSlider.GetPos());
	_parameters->SetItemBufferResolution(rez);
	CStringA text;
	text.Format("%i x %i", rez, rez);
	SetDlgItemTextW(IDC_STATIC_ITEM_BUFFER, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderSubdivision(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	_parameters->SetSubdivisionLevel(_subdivisionSlider.GetPos());
	CStringA text;
	text.Format("%i", _subdivisionSlider.GetPos());
	SetDlgItemTextW(IDC_STATIC_SUBDIVISION, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderFPS(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	_parameters->SetRequestedFPS(_fpsSlider.GetPos());
	CStringA text;
	text.Format("%i", _fpsSlider.GetPos());
	SetDlgItemTextW(IDC_STATIC_FPS, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderShootLevel(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	_parameters->SetShootLevel(_shootLevelSlider.GetPos());
	CStringA text;
	text.Format("%i", _shootLevelSlider.GetPos());
	SetDlgItemTextW(IDC_STATIC_SHOOT_LEVEL, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderFovAngle(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	_parameters->SetFovAngle(_fovAngleSlider.GetPos());
	CStringA text;
	text.Format("%i", _fovAngleSlider.GetPos());
	SetDlgItemTextW(IDC_STATIC_FOV_ANGLE, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderFovDecayInterval(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	_parameters->SetFovDecayInterval(_fovDecayIntervalSlider.GetPos());
	CStringA text;
	text.Format("%i", _fovDecayIntervalSlider.GetPos());
	SetDlgItemTextW(IDC_STATIC_FOV_DECAY_INTERVAL, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnNMCustomdrawSliderUnshotMipmapShootLevel(NMHDR *pNMHDR, LRESULT *pResult)
{
	pNMHDR;

	UpdateData(true);
	_parameters->SetUnshotMipmapShootLevel(_unshotMipmapShootLevelSlider.GetPos());
	CStringA text;
	text.Format("%i", _unshotMipmapShootLevelSlider.GetPos());
	SetDlgItemTextW(IDC_STATIC_UNSHOT_MIPMAP_SHOOT_LEVEL, CString(text));
	*pResult = 0;
}

void CFovDrivenRadiosityDlg::OnEnChangeEditMeshFilename()
{
	UpdateData(true);
	CStringA temp(_meshFilename);
	_parameters->SetMeshFilename(std::string(temp));
}

